package de.tu_darmstadt.gdi1.towerdefense.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import translator.TranslatableGUIElement;
import translator.Translator;
import de.tu_darmstadt.gdi1.towerdefense.controller.TowerDefenseController;
import de.tu_darmstadt.gdi1.towerdefense.exceptions.InternalFailureException;
import de.tu_darmstadt.gdi1.towerdefense.exceptions.ParameterOutOfRangeException;
import de.tu_darmstadt.gdi1.towerdefense.model.MapLoadedUpdate;
import de.tu_darmstadt.gdi1.towerdefense.model.TowerDefenseModel;

/**
 * the window class of the games view
 */
public class StudentWindow extends GameWindow implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3786880738388799295L;
	/**
	 * instance of the frame visualizing the player information
	 */
	private PlayerFrame playerFrame;
	/**
	 * instance of the frame with the tower build buttons
	 */
	private TowerFrame towerFrame;
	/**
	 * window reference for the information menu
	 */
	private static StudentWindow MainWindow;
	/**
	 * reference to the TowerDefenseModel
	 */
	private TowerDefenseModel model;
	/**
	 * reference to the menu bar
	 */
	private JMenuBar menuBar = new JMenuBar();;
	/**
	 * reference to the menu items
	 */
	private Vector<JMenuItem> menuItems;
	/**
	 * instance of the translator
	 */
	Translator translator = new Translator("T_I18N", Locale.GERMANY);
	/**
	 * instance of the guiBuilder
	 */
	private TranslatableGUIElement guiBuilder = translator.getGenerator();

	/**
	 * constructor
	 * 
	 * @param windowTitle
	 */
	public StudentWindow(String windowTitle) {
		super(windowTitle);
		menuItems = new Vector<JMenuItem>();
		setUp();

		createGamePanel();
		playerFrame = new PlayerFrame();
		towerFrame = new TowerFrame();
		Container pane = getContentPane();
		pane.setLayout(new BorderLayout());
		pane.add(gamePanel, BorderLayout.CENTER);
		pane.add(playerFrame, BorderLayout.SOUTH);
		pane.add(towerFrame, BorderLayout.EAST);
		pane.setSize(gamePanel.getWidth() + towerFrame.getWidth(),
				gamePanel.getHeight() + playerFrame.getHeight());
		pane.setVisible(true);

	}

	/**
	 * create a new game panel for the game's visual representation
	 */
	@Override
	protected GamePanel createGamePanel() {
		return new MainFrame(this);
	}

	/**
	 * set up the game window and the menu bar
	 */
	public void setUp() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setResizable(false);
		setSize(600, 600);
		setJMenuBar(menuBar);
		menu01();
		info();
		einstellungen();
		language();

	}

	/**
	 * setup the file menu add the menu Items Start, save, beenden
	 * 
	 */
	public void menu01() {
		JMenu fileMenu = new JMenu("Menue");

		JMenuItem start = guiBuilder.generateJMenuItem("start");
		start.setActionCommand("start");
		menuItems.add(start);
		JMenuItem save = guiBuilder.generateJMenuItem("save");
		save.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					model.readLevel();
				} catch (IOException e1) {
					e1.printStackTrace();
				}

			}
		});

		save.setActionCommand("save");
		menuItems.add(save);
		JMenuItem end = guiBuilder.generateJMenuItem("beenden");
		end.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0); // exit
			}
		});

		fileMenu.add(start);
		fileMenu.add(save);
		fileMenu.add(end);

		menuBar.add(fileMenu);
	}

	/**
	 * setup the info menu add the menu info of the team, and a help windo
	 * 
	 */
	public void info() {
		JMenu fileMenu = guiBuilder.generateJMenu("info");

		JMenuItem team = guiBuilder.generateJMenuItem("team");
		team.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(MainWindow,
						"Programmiert von : \n Bunten, Jan Simon  "
								+ "\n Schelmbauer, Markus  "
								+ "\n Stickl, Ralf ");
			}
		});

		JMenuItem help = guiBuilder.generateJMenuItem("help");
		help.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				JOptionPane
						.showMessageDialog(MainWindow,
								" Bei fragen besuchen sie www.hilfe.de \n oder wenden sie sich an das Personal");
			}
		});
		fileMenu.add(team);
		fileMenu.add(help);

		menuBar.add(fileMenu);
	}

	/**
	 * setup the option menu add the menu settings,
	 */
	public void einstellungen() {
		JMenu fileMenu = guiBuilder.generateJMenu("extras");
		JMenuItem settings = guiBuilder.generateJMenuItem("settings");
		fileMenu.add(settings);
		menuBar.add(fileMenu);
	}

	/**
	 * setup the language menu add the language, deutsch, english and ital
	 */
	public void language() {
		JMenu fileMenu = guiBuilder.generateJMenu("language");

		JMenuItem deutsch = guiBuilder.generateJMenuItem("deutsch");
		deutsch.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				translator.setTranslatorLocale(Locale.GERMANY);
			}
		});

		JMenuItem englisch = guiBuilder.generateJMenuItem("englisch");
		englisch.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				translator.setTranslatorLocale(Locale.ENGLISH);

			}
		});
		JMenuItem ital = guiBuilder.generateJMenuItem("ital");
		ital.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				translator.setTranslatorLocale(Locale.US);

			}
		});

		fileMenu.add(deutsch);
		fileMenu.add(englisch);
		fileMenu.add(ital);
		menuBar.add(fileMenu);
	}

	/**
	 * redraw all the panels
	 */
	public void redrawPanels() {
		try {
			gamePanel.redraw();
		} catch (InternalFailureException e) {
			e.printStackTrace();
		}
	}

	/**
	 * add a reference to the Tower Defense Model
	 * 
	 * @param m
	 *            the tower defense model
	 */
	public void addModel(TowerDefenseModel m) {
		MainFrame s = (MainFrame) gamePanel;
		s.addModel(m);
		playerFrame.addModel(m);
		model = m;
	}

	/**
	 * called when the model has changed
	 */
	@Override
	public void update(Observable o, Object arg) {
		if (arg instanceof MapLoadedUpdate)
			initializeLevel();
		redrawPanels();
	}

	/**
	 * initialize the level
	 */
	public void initializeLevel() {

		// redraw panel with new level information
		try {
			gamePanel.notifyLevelLoaded(model.getOriginalMap()[0].length,
					model.getOriginalMap().length);
		} catch (ParameterOutOfRangeException e) {
			e.printStackTrace();
		} catch (InternalFailureException e) {
			e.printStackTrace();
		}

		// update pane size
		Container pane = getContentPane();
		try {
			gamePanel.redraw();
		} catch (InternalFailureException e) {
			e.printStackTrace();
		}
		pane.setSize(gamePanel.getWidth() + towerFrame.getWidth(),
				gamePanel.getHeight() + playerFrame.getHeight());
		setSize(pane.getSize());
	}

	/**
	 * getter for the tower frame
	 * 
	 * @return the tower frame
	 */
	public TowerFrame getTowerFrame() {
		return towerFrame;
	}

	/**
	 * add the controller as listener to the menu items
	 * 
	 * @param c
	 *            the tower defense controller
	 */
	public void addMenuListeners(TowerDefenseController c) {
		for (Iterator<JMenuItem> items = menuItems.iterator(); items.hasNext();) {
			JMenuItem item = items.next();
			item.addActionListener(c);
		}
	}

	/**
	 * prints out that the game is lost
	 */
	public void gameIsLost() {
		JOptionPane.showMessageDialog(MainWindow, "You loose!!");
	}

	/**
	 * prints out that the game is won
	 */
	public void gameIsWon() {
		JOptionPane.showMessageDialog(MainWindow, "Win Win :-) ");
	}

	public PlayerFrame getPlayerFrame() {
		return playerFrame;
	}

}